#ifndef __SA_MATCH_H__
#define __SA_MATCH_H__


#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include "cuda_header.h"
#include "QuerySet.h"
#include "Reference.h"
#include "GPUSAMatch_kernel.h"

using namespace std;


class SAMatch {
protected:
	vector<st_SA> _sa;
	unsigned int* _saIndex;
public:
	SAMatch(unsigned int* i_saIndex){
		_saIndex = i_saIndex;
	};
	~SAMatch() {};

	
	void add(const uint3 saValue, const char saOffset);
	void clear();
	size_t size() {return _sa.size();}
	virtual void match(QuerySet& querySet, Reference &ref, 
			const int numMismatch) = 0;

protected:
	void getPos(vector<unsigned int> &pos, const st_SA &sa);
};




//for result validication, not for efficiency
class CPUSAMatch : public SAMatch {
public:
	CPUSAMatch(unsigned int* i_saIndex) :
		SAMatch(i_saIndex) {};

	void match(QuerySet &querySet, Reference &ref, const int numMismatch);
private:
	bool isMatched(const char* seq, const char* ref, 
			const int readLength, const int numMismatch);
	//@return the number of alignments
	int matchReadToRef(const char* read, 
			vector<unsigned int> &pos, const char saOffset,
			const int readLength, const char* ref, 
			const int numMismatch);
};



//for efficiency
class GPUSAMatch : public SAMatch {
public:
	GPUSAMatch(unsigned int* i_saIndex) : 
		SAMatch(i_saIndex) {};
	void match(QuerySet &querySet, Reference &ref, const int numMismatch); 
};


#endif /*__SA_MATCH_H__*/
